home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / rpcdcpro / client.cpp next >
C/C++ Source or Header  |  1998-08-07  |  9KB  |  254 lines

  1. //-----------------------------------------------------------------------------
  2. // This program illustrates a simple tcp/udp client implementation
  3. //-----------------------------------------------------------------------------
  4.  
  5. #ifdef WIN32
  6.     #include <windows.h>
  7. #endif
  8.  
  9. #include <stdio.h>
  10. #include <time.h>
  11.  
  12. #include <rpcdc.h>
  13.  
  14. //-----------------------------------------------------------------------------
  15. // Here is a definition of a structure that must be transmitted to the server
  16. // One possibility is to develop a specific XDR function, used with transmit/
  17. // receive functions
  18. //-----------------------------------------------------------------------------
  19. typedef struct _TEST {
  20.  
  21.     int i1;
  22.     int i2;
  23.     int i3;
  24.  
  25.     float f;
  26.     double d;
  27.  
  28. } TEST;
  29.  
  30. //-----------------------------------------------------------------------------
  31. // First write the XDR function - standard structure
  32. // The parameters are as follows :
  33. //      h : (void *) points to the host binary representation of the data
  34. //      n : (void *) points to the network binary representation of the data
  35. //      code : indicates the operation to perform (3 possibilities)
  36. //              --> XDR_ENCODE : conversion h -> n
  37. //              --> XDR_DECODE : conversion n -> h
  38. //              --> XDR_MEMORY : just returns the size of the object
  39. //-----------------------------------------------------------------------------
  40. size_t _xdr_TEST (void *h, void *n, int code)
  41.  
  42. {       
  43.     TEST *hi=(TEST *)h;             // first convert pointers
  44.     char *ni=(char *)n;
  45.     size_t size;
  46.     
  47.     switch (code) {
  48.  
  49.     case XDR_ENCODE: 
  50.     case XDR_DECODE:
  51.         
  52.         size=_xdr_int(NULL,NULL,XDR_MEMORY);
  53.         _xdr_int((void *)&hi->i1,(void *)ni,code);   ni+=size;
  54.         _xdr_int((void *)&hi->i2,(void *)ni,code);   ni+=size;
  55.         _xdr_int((void *)&hi->i3,(void *)ni,code);   ni+=size;
  56.         
  57.         size=_xdr_float(NULL,NULL,XDR_MEMORY);
  58.         _xdr_float((void *)&hi->f,(void *)ni,code);  ni+=size;
  59.         
  60.         size=_xdr_double(NULL,NULL,XDR_MEMORY);
  61.         _xdr_double((void *)&hi->d,(void *)ni,code); ni+=size;
  62.         return 0;
  63.  
  64.     case XDR_MEMORY:
  65.     default:
  66.         return 3*_xdr_int(NULL,NULL,XDR_MEMORY)+
  67.                  _xdr_float(NULL,NULL,XDR_MEMORY)+
  68.                  _xdr_double(NULL,NULL,XDR_MEMORY);
  69.     }
  70. }
  71.  
  72. //-----------------------------------------------------------------------------
  73. // Now the function to send a TEST structure becomes very simple !
  74. // The following example returns 1 if success, 0 if a problem occurs.
  75. // Binary conversion is automatically performed through the XDR routine
  76. // written above.
  77. // Warning : remember to call _rpc_flush() !
  78. //-----------------------------------------------------------------------------
  79. int _rpcsend_TEST (SOCKET Socket, 
  80.                    RPC_MSG *rpc_msg, XDR_BUFFER *xdr_buffer,
  81.                    TEST *TestParameter)
  82.  
  83. {   
  84.     return _rpcsend_buffer(Socket,rpc_msg,xdr_buffer,TestParameter,_xdr_TEST)==
  85.            _xdr_TEST(NULL,NULL,XDR_MEMORY);
  86. }
  87.  
  88. //-----------------------------------------------------------------------------
  89. // Similarly, the function to receive a TEST structure is also simple.
  90. // Binary conversion is automatically performed through the XDR routine
  91. // written above.
  92. //-----------------------------------------------------------------------------
  93. int _rpcrecv_TEST (SOCKET Socket, 
  94.                    XDR_BUFFER *xdr_buffer,
  95.                    TEST *TestParameter)
  96.          
  97. {
  98.     return _rpcrecv_buffer(Socket,xdr_buffer,TestParameter,_xdr_TEST)==
  99.            _xdr_TEST(NULL,NULL,XDR_MEMORY);         
  100. }
  101.  
  102. //-----------------------------------------------------------------------------
  103. // tcp client implementation
  104. //-----------------------------------------------------------------------------
  105. void mainTCP (char *server, char *service)
  106.  
  107. {
  108.     SOCKET Socket;              // to communicate with the server     
  109.     RPC_MSG rpc_msg;            // for transmission buffering
  110.     XDR_BUFFER xdr_buffer;      // for XDR buffering
  111.     char msg[256];
  112.     int ans;
  113.     time_t t;
  114.     TEST Test;
  115.  
  116.     time(&t);
  117.     
  118. // Initialization of the TEST structure
  119.     Test.i1=10;
  120.     Test.i2=17;
  121.     Test.i3=25;
  122.     Test.f=3.14159f;
  123.     Test.d=2.7182818;
  124.  
  125. // Connection request to the specified server, with the specified service
  126.     Socket=_StartTCPClient(server,
  127.                            service,
  128.                            10,
  129.                            &rpc_msg,
  130.                            &xdr_buffer);
  131.  
  132. // An error occured, or the connection has been rejected    
  133.     if (Socket==0) {
  134.         _GetErrMsg(msg);
  135.         printf("%s\n",msg);
  136.         return;
  137.     }
  138.  
  139. // Now the connection has been accepted !
  140.     
  141. // The first int (value 1) corresponds to the first rpc message transmitted to the server    
  142.     _rpcsend_int(Socket,&rpc_msg,&xdr_buffer,1);
  143. // This message also uses an additionnal parameter (int) : here the local time 
  144.     _rpcsend_int(Socket,&rpc_msg,&xdr_buffer,(int)t);
  145. // The last part of the message is made of the TEST structure defined above
  146.     _rpcsend_TEST(Socket,&rpc_msg,&xdr_buffer,&Test);
  147. // flushing is required !
  148.     _rpc_flush(Socket,&rpc_msg);
  149.  
  150. // Now I am waiting for the answer coming from the server !
  151. // In this example, the first int is modified and returned, same for the TEST structure.
  152.     _rpcrecv_int(Socket,&xdr_buffer,&ans);
  153.     _rpcrecv_TEST(Socket,&xdr_buffer,&Test);
  154.     printf("Message sent to server : %d\n",t);
  155.     printf("Server answered        : %d\n",ans);
  156.     printf("New TEST               : %d %d %d %g %lg\n",Test.i1,Test.i2,Test.i3,Test.f,Test.d);
  157.  
  158. // OK ! seems to work, bye !
  159.     _StopTCPClient(Socket,&rpc_msg,&xdr_buffer);
  160. }
  161.  
  162. //-----------------------------------------------------------------------------
  163. // udp client implementation
  164. //-----------------------------------------------------------------------------
  165. void mainUDP (char *service)
  166.  
  167. {
  168.     SOCKET udpSocket;
  169.     sockaddr_in bcast_addr,src_addr;
  170.     long int udpQuery;
  171.     int end,stat,len;
  172.     struct hostent *host;
  173.     time_t t1,t2;
  174.     struct timeval timeout={0,0};
  175.     char sz_info[256];
  176.     struct {
  177.         long int udpResponse;
  178.         char szb[128];
  179.     } udp;
  180.  
  181. // Creation of the socket corresponding to the specified service
  182.     udpSocket=_StartUDPClient(service,10,&bcast_addr);
  183.     if (udpSocket==0) {
  184.         _GetErrMsg(sz_info);
  185.         printf("%s\n",sz_info); 
  186.         return;
  187.     }
  188.  
  189. // The udp message is 32 bits long, the value is just 1 in this example
  190.     udpQuery=htonl(1);
  191.     stat=sendto(udpSocket,(char *)&udpQuery,sizeof(long int),0,
  192.                 (const struct sockaddr *)&bcast_addr,sizeof(sockaddr_in));
  193.     if (stat!=sizeof(long int)) {
  194.         _StopUDPClient(udpSocket);
  195.         return; 
  196.     }
  197.  
  198. // Now I am waiting for answers coming from the different servers, max. delay 10 seconds
  199.     time(&t1);
  200.     end=0;
  201.     do {
  202.         switch (_socket_ready_r(udpSocket,&timeout)) {
  203.         case -1:                    // this is an error !
  204.             end=1;
  205.             break;
  206.         case 0:                     // no error, socket not ready !
  207.             time(&t2);
  208.             end=(t2-t1)>10;
  209.             break;
  210.         default:                    // no error, socket ready !
  211.             len=sizeof(src_addr);
  212.             stat=recvfrom(udpSocket,(char *)&udp,sizeof(udp),0,
  213.                           (struct sockaddr *)&src_addr,&len);
  214.             if (stat==sizeof(udp)) {
  215.                 udp.udpResponse=ntohl(udp.udpResponse);
  216.                 switch (udp.udpResponse) {
  217.                 case 2:                             // the server answers 2 (1+udpQuery) : good !
  218.                     strcpy(sz_info,udp.szb); 
  219.                     break;
  220.                 default:
  221.                     strcpy(sz_info,""); 
  222.                 }
  223.                 if (strlen(sz_info)!=0) {
  224.                     host=gethostbyaddr((char *)&src_addr.sin_addr,sizeof(struct in_addr),PF_INET);
  225.                     if (host!=NULL) printf("%s : ",host->h